<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { NAvatar, NButton, NCard, NCarousel, NDivider, NModal, NTag, useMessage } from 'naive-ui';
import { fetchGameDetail, fetchGameReviews } from '@/service/api/game';
import { fetchUserInfo } from '@/service/api/user';
import { purchaseGame } from '@/service/api/purchase';
import { useAuthStore } from '@/store/modules/auth';
import { useTabStore } from '@/store/modules/tab';

const route = useRoute();
const router = useRouter();
const message = useMessage();
const authStore = useAuthStore();
const tabStore = useTabStore();

const gameId = ref<number | null>(null);
const gameInfo = ref<any>(null);
const loading = ref(false);
const userBalance = ref<number>(0);
const balanceLoading = ref(false);

const reviews = ref<any[]>([]);
// 1. 移除 debugInfo.value = []、debugInfo.value.push(...)、页面调试信息展示、console.log 等调试相关内容

// 购买相关状态
const showPurchaseModal = ref(false);
const purchaseLoading = ref(false);
const errorMessage = ref('');

// 1. 增加开发商、操作说明、轮播图等数据
const developer = ref('');
const instructions = ref('');
const sliderImages = ref<string[]>([]);

function highlightKeys(raw: string): string {
  if (!raw) return '';
  let text = raw;
  const keycapList = ['鼠标左键', '鼠标右键', 'ESC', '空格', 'E', 'W', 'A', 'S', 'D'];
  keycapList.forEach(key => {
    // 只替换未被keycap包裹的
    const reg = new RegExp(`(?<!<span class="keycap">)${key}(?!</span>)`, 'g');
    text = text.replace(reg, `<span class="keycap">${key}</span>`);
  });
  text = text.replace(/\n/g, '<br>');
  return text;
}

async function loadExtraInfo(game: any) {
  developer.value = '';
  instructions.value = '';
  sliderImages.value = [];
  if (game && game.pic) {
    const base = game.pic.endsWith('/') ? game.pic : `${game.pic}/`;
    // 轮播图路径
    const sliderPaths = Array.from({ length: 3 }, (_, i) => `${base}assets/main/img/slider${i + 1}.png`);
    // Instructions路径
    const instructionsPath = `${base}assets/main/Instructions`;
    // developer路径
    const developerPath = `${base}assets/main/developer`;
    // 读取开发商
    try {
      const devRes = await fetch(developerPath);
      developer.value = await devRes.text();
    } catch {
      developer.value = '未知开发商';
    }
    // 读取操作说明
    try {
      const insRes = await fetch(instructionsPath);
      const rawText = await insRes.text();
      instructions.value = highlightKeys(rawText);
    } catch {
      instructions.value = '暂无操作说明';
    }
    // 轮播图
    sliderImages.value = sliderPaths;
  }
}

// 计算属性
const hasEnoughBalance = computed(() => userBalance.value >= (gameInfo.value?.price || 0));
const canPurchase = computed(() => !loading.value && !balanceLoading.value && gameInfo.value && hasEnoughBalance.value);

// 获取真实游戏ID
function getGameId(game: any) {
  return game?.gameId ?? game?.id;
}
// 拉取评论并补全用户名（借鉴 gamelibrary）
async function loadReviews(gameIdParam: number) {
  if (!gameIdParam) return;
  try {
    const res = await fetchGameReviews(gameIdParam);
    const list = Array.isArray(res) ? res : (res?.data ?? []);
    // 批量查用户名
    const userIdSet = Array.from(new Set(list.map(item => item.userId || item.user_id)));
    const userMap: Record<string, string> = {};
    await Promise.all(
      userIdSet.map(async uid => {
        if (!uid) return;
        try {
          const { data } = await fetchUserInfo(uid);
          if (data && data.username) userMap[uid] = data.username;
        } catch {}
      })
    );
    // 合并用户名
    reviews.value = list.map(item => ({
      ...item,
      username: userMap[item.userId || item.user_id] || `用户${item.userId || item.user_id}`
    }));
  } catch {
    reviews.value = [];
  }
}

onMounted(async () => {
  let localGame = null;
  if (route.query.game) {
    try {
      localGame = JSON.parse(route.query.game as string);
    } catch {
      // do nothing
    }
  }
  const id = route.query.id || route.params.id;
  let detail: any = {};
  if (id) {
    const res = await fetchGameDetail(Number(id));
    detail = res.data || {};
  }
  gameInfo.value = {
    ...detail,
    ...(localGame || {}),
    pic: ((localGame && (localGame as any).pic) || detail.pic) as string
  };
  await loadExtraInfo(gameInfo.value);
  await loadReviews(getGameId(gameInfo.value));
  await loadUserBalance();
});

// 2. 在加载游戏信息后调用 loadExtraInfo
async function loadGameInfo() {
  if (!gameId.value) return;
  loading.value = true;
  try {
    const res = await fetchGameDetail(gameId.value);
    gameInfo.value = res.data || {
      gameId: gameId.value,
      gameName: '游戏详情',
      gameCategory: '未知分类',
      description: '暂无描述',
      cover: '/banner/slide1.png',
      screenshots: ['/banner/slide1.png', '/banner/slide2.png', '/banner/slide3.png'],
      price: 0
    };
    await loadExtraInfo(gameInfo.value);
  } catch {
    message?.error('获取游戏信息失败');
    // 使用默认数据
    gameInfo.value = {
      gameId: gameId.value,
      gameName: '游戏详情',
      gameCategory: '未知分类',
      description: '暂无描述',
      cover: '/banner/slide1.png',
      screenshots: ['/banner/slide1.png', '/banner/slide2.png', '/banner/slide3.png'],
      price: 0
    };
    await loadExtraInfo(gameInfo.value);
  } finally {
    loading.value = false;
  }
}

// 加载用户余额
async function loadUserBalance() {
  balanceLoading.value = true;
  try {
    const userId = authStore.userInfo.userId;
    if (!userId) {
      userBalance.value = 0;
      return;
    }
    const res = await fetchUserInfo(userId.toString());
    let balance = 0;
    if (res.data?.accountBalance !== undefined && res.data?.accountBalance !== null) {
      if (typeof res.data.accountBalance === 'string') {
        balance = Number.parseFloat(res.data.accountBalance);
      } else {
        balance = res.data.accountBalance;
      }
      if (Number.isNaN(balance)) balance = 0;
    }
    userBalance.value = balance;
  } catch {
    userBalance.value = 0;
  } finally {
    balanceLoading.value = false;
  }
}

// 显示购买确认对话框
function showPurchaseConfirm() {
  if (!canPurchase.value) {
    return;
  }
  showPurchaseModal.value = true;
}

// 确认购买游戏
async function confirmPurchase() {
  if (!gameInfo.value || !getGameId(gameInfo.value)) {
    message?.error('游戏信息不完整');
    return;
  }
  if (!hasEnoughBalance.value) {
    errorMessage.value = '余额不足，无法购买此游戏';
    return;
  }
  purchaseLoading.value = true;
  errorMessage.value = '';
  try {
    const purchaseData = {
      userId: Number(authStore.userInfo.userId),
      gameId: getGameId(gameInfo.value)
    };

    // 执行购买请求
    await purchaseGame(purchaseData);

    // 购买成功 - 直接提示成功并跳转
    message?.success('购买成功！游戏已添加到您的游戏库');
    showPurchaseModal.value = false;
    await loadUserBalance(); // 刷新余额
    await tabStore.removeActiveTab();
    router.push(`/gamelibrary?highlight=${getGameId(gameInfo.value)}`);
  } catch (err) {
    console.error('购买异常:', err);

    // 只有在网络异常或其他系统错误时才显示错误
    if ((err as any)?.response?.data?.msg) {
      const errorMsg = (err as any).response.data.msg;
      if (errorMsg.includes('已购买')) {
        message?.info(errorMsg);
        showPurchaseModal.value = false;
        await tabStore.removeActiveTab();
        router.push('/gamelibrary');
      } else {
        message?.error(errorMsg);
      }
    } else {
      message?.error('网络连接异常，请稍后重试');
    }
  } finally {
    purchaseLoading.value = false;
  }
}

// 取消购买
function cancelPurchase() {
  showPurchaseModal.value = false;
  errorMessage.value = '';
}

function getCoverUrl(game: any) {
  if (game && game.pic) {
    const base = game.pic.endsWith('/') ? game.pic : `${game.pic}/`;
    return `${base}assets/main/game-logo.svg`;
  }
  return '@/assets/imgs/game-logo.svg';
}
</script>

<template>
  <div class="game-detail-container">
    <!-- 返回按钮 -->
    <div class="back-button-container">
      <NButton
        text
        class="back-button"
        :style="{
          background: 'rgba(255, 255, 255, 0.9)',
          backdropFilter: 'blur(10px)',
          border: '1px solid rgba(0, 0, 0, 0.1)',
          borderRadius: '8px',
          padding: '8px 16px',
          boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)'
        }"
        @click="router.back()"
      >
        <template #icon>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path
              d="M19 12H5M12 19L5 12L12 5"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
        </template>
        返回
      </NButton>
    </div>
    <div v-if="loading" class="loading-container">
      <div class="loading-spinner"></div>
      <p>正在加载游戏信息...</p>
    </div>
    <div v-else-if="!gameInfo" class="error-container">
      <div class="error-icon">⚠️</div>
      <h2>游戏信息加载失败</h2>
      <p>抱歉，无法获取游戏信息，请稍后重试</p>
      <NButton type="primary" @click="loadGameInfo">重新加载</NButton>
    </div>
    <NCard v-else-if="gameInfo" class="game-detail-card" :content-style="{ padding: '0' }" hoverable>
      <!-- 轮播图 -->
      <div class="screenshots-carousel-16-9-wrapper">
        <NCarousel class="screenshots-carousel-16-9" show-arrow dot-type="line" :autoplay="true" :interval="4000">
          <template v-for="(img, idx) in sliderImages" :key="idx">
            <div class="carousel-img-16-9">
              <img :src="img" :alt="(gameInfo?.gameName || gameInfo?.name) + '截图' + (idx + 1)" />
            </div>
          </template>
        </NCarousel>
      </div>
      <div class="header">
        <NAvatar :src="getCoverUrl(gameInfo)" size="large" round class="logo" />
        <div>
          <h1 class="game-title">{{ gameInfo?.gameName || gameInfo?.name || '游戏详情' }}</h1>
          <div class="game-tags">
            <NTag type="info" size="small" style="margin-right: 8px">ID: {{ gameInfo?.gameId || gameInfo?.id }}</NTag>
            <NTag type="primary" size="small">{{ gameInfo?.gameCategory || gameInfo?.category }}</NTag>
            <NTag type="success" size="small" style="margin-left: 8px">¥{{ gameInfo?.price }}</NTag>
          </div>
        </div>
      </div>
      <NDivider style="margin: 16px 0" />
      <div class="info">
        <div class="info-row">
          <span>开发商：</span>
          <span class="desc">{{ developer }}</span>
        </div>
        <div class="info-row">
          <span>游戏价格：</span>
          <span class="desc price">¥{{ gameInfo?.price }}</span>
        </div>
        <div class="info-row">
          <span>游戏评分：</span>
          <span class="desc">
            <NRate :value="gameInfo?.score" readonly allow-half size="small" style="margin-right: 8px" />
            <span style="color: #faad14; font-weight: 600">{{ gameInfo?.score }}</span>
          </span>
        </div>
      </div>
      <!-- 购买按钮区域 -->
      <div v-if="!gameInfo?.owned" class="actions">
        <NButton type="primary" size="large" class="start-btn" :disabled="!canPurchase" @click="showPurchaseConfirm">
          {{ hasEnoughBalance ? `购买游戏 ¥${gameInfo?.price}` : `余额不足 ¥${gameInfo?.price}` }}
        </NButton>
      </div>
      <NDivider style="margin: 16px 0" />
      <!-- 游戏详细介绍模块 -->
      <section class="game-section">
        <h2 class="section-title">详细简介</h2>
        <p class="section-content">{{ gameInfo?.description }}</p>
      </section>
      <!-- 游戏操作说明模块 -->
      <section class="game-section">
        <h2 class="section-title">游戏操作说明</h2>
        <div class="section-content" v-html="instructions"></div>
      </section>
      <!-- 评论区展示（无输入框） -->
      <section class="game-section">
        <h2 class="section-title">游戏评论</h2>
        <div class="comments">
          <template v-if="reviews.filter(r => r.rating === 5).length">
            <div class="comment-group-title">特别好评</div>
            <div v-for="item in reviews.filter(r => r.rating === 5)" :key="item.id" class="comment-item">
              <NAvatar :size="32" style="margin-right: 8px; vertical-align: middle" />
              <b>{{ item.username }}：</b>
              <NRate :value="item.rating" readonly size="small" style="margin: 0 8px" />
              <span>{{ item.comment }}</span>
            </div>
          </template>
          <template v-if="reviews.filter(r => r.rating < 5).length">
            <div class="comment-group-title">其他评论</div>
            <div v-for="item in reviews.filter(r => r.rating < 5)" :key="item.id" class="comment-item">
              <NAvatar :size="32" style="margin-right: 8px; vertical-align: middle" />
              <b>{{ item.username }}：</b>
              <NRate :value="item.rating" readonly size="small" style="margin: 0 8px" />
              <span>{{ item.comment }}</span>
            </div>
          </template>
          <div v-if="!reviews.length" class="comment-item">暂无评论</div>
        </div>
      </section>
      <!-- 购买弹窗 -->
      <NModal v-model:show="showPurchaseModal" preset="dialog" title="确认购买" :loading="purchaseLoading">
        <div class="purchase-modal-content">
          <div class="purchase-game-info">
            <img :src="sliderImages[0]" class="purchase-game-cover" />
            <div class="purchase-game-details">
              <h3>{{ gameInfo?.gameName }}</h3>
              <div class="purchase-game-category">{{ gameInfo?.gameCategory }}</div>
              <div class="purchase-game-price">¥{{ gameInfo?.price }}</div>
            </div>
          </div>
          <div class="balance-info">
            <div class="balance-row">
              <span>当前余额：</span>
              <span class="balance-amount" :class="[{ insufficient: !hasEnoughBalance }]">¥{{ userBalance }}</span>
            </div>
            <div class="balance-row">
              <span>购买后余额：</span>
              <span class="remaining-balance" :class="[{ negative: !hasEnoughBalance }]">
                ¥{{ (userBalance - (gameInfo?.price || 0)).toFixed(2) }}
              </span>
            </div>
          </div>
          <div v-if="!hasEnoughBalance" class="insufficient-balance-warning">余额不足，无法购买此游戏</div>
          <div v-if="errorMessage" class="purchase-error">{{ errorMessage }}</div>
        </div>
        <template #action>
          <NButton :disabled="purchaseLoading" @click="cancelPurchase">取消</NButton>
          <NButton
            type="primary"
            :loading="purchaseLoading"
            :disabled="!hasEnoughBalance || purchaseLoading"
            @click="confirmPurchase"
          >
            确认购买
          </NButton>
        </template>
      </NModal>
    </NCard>
  </div>
</template>

<style scoped>
/* 以下内容完全复制自 gamelibrary 的 <style scoped>，保证样式一致 */
.gamelibrary-container {
  display: flex;
  height: 100vh;
  min-height: 0;
  background: var(--background-color);
  font-family: var(--font-family-main);
  border-radius: 0;
  box-shadow: none;
  margin: 0;
  max-width: none;
  overflow: auto;
}
.type-list {
  width: 260px;
  background: #f5f7fa;
  color: var(--text-color-main);
  border-right: 1px solid var(--border-color);
  overflow-y: auto;
  overflow-x: hidden;
  box-shadow: none;
  border-radius: 0;
  margin: 0;
  height: 100%;
}
.type-list ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.type-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 16px;
  cursor: pointer;
  border-bottom: 1px solid #e0e6ed;
  font-size: 18px;
  font-weight: 700;
  background: #eaf1fb;
  box-shadow: 0 2px 8px #1976d211;
  transition:
    background 0.2s,
    color 0.2s,
    font-weight 0.2s,
    box-shadow 0.2s,
    transform 0.1s;
  letter-spacing: 0.5px;
  user-select: none;
  border-radius: 16px 16px 0 0;
}
.type-header:hover {
  background: #d2e6fa;
  color: #1976d2;
  font-weight: 800;
  box-shadow: 0 4px 16px #1976d233;
  transform: translateX(2px) scale(1.03);
}
.type-header:active {
  background: #e6f0fa;
  color: var(--primary-color-hover);
  font-weight: 700;
  box-shadow: var(--shadow-main);
  transform: scale(0.98);
}
.arrow {
  transition:
    transform 0.2s,
    color 0.2s;
  font-size: 13px;
  color: #bbb;
}
.arrow.open {
  transform: rotate(180deg);
  color: var(--primary-color);
}
.game-sub-list {
  background: #fff;
  padding: 8px 0 8px 0;
  border-radius: 0 0 16px 16px;
  margin: 0 8px 12px 8px;
  box-shadow: 0 2px 12px #1976d211;
  border: 1px solid #e0e6ed;
  overflow: visible;
}
.game-sub-list li {
  padding: 13px 28px;
  cursor: pointer;
  border-bottom: 1px solid #f0f0f0;
  font-size: 15px;
  color: #4a5a6a;
  background: transparent;
  transition:
    background 0.2s,
    color 0.2s,
    font-weight 0.2s,
    box-shadow 0.2s,
    transform 0.1s;
  border-left: 3px solid transparent;
  border-radius: 8px;
  user-select: none;
  letter-spacing: 0.2px;
  margin: 4px 8px;
}
.game-sub-list li:hover {
  background: #eaf1fb;
  color: #1976d2;
  font-weight: 700;
  box-shadow: 0 2px 8px #1976d233;
  transform: translateX(4px) scale(1.04);
}
.game-sub-list li:active {
  background: #d2e6fa;
  color: var(--primary-color-hover);
  font-weight: 700;
  box-shadow: var(--shadow-main);
  transform: scale(0.97);
}
.game-sub-list li.active {
  background: #d2e6fa;
  color: #1976d2;
  border-left: 3px solid #1976d2;
  font-weight: 800;
  box-shadow: 0 4px 16px #1976d233;
}

.game-detail-pane {
  flex: 1 1 0%;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 0;
  background: var(--background-color);
}
.game-detail-card {
  background: var(--background-color);
  border-radius: var(--radius-card);
  padding: 40px 48px 32px 48px;
  box-shadow: var(--shadow-main);
  width: 100%;
  display: block;
  transition: box-shadow 0.2s;
}
.game-detail-card:hover {
  box-shadow: 0 8px 32px #1976d244;
}
.header {
  display: flex;
  align-items: center;
  gap: var(--gap-md);
  margin-bottom: var(--gap-md);
}
.logo {
  width: 56px;
  height: 56px;
  border-radius: 8px;
  object-fit: cover;
  background: #f0f0f0;
}
.game-title {
  font-size: var(--font-size-title);
  font-weight: 700;
  color: var(--primary-color);
  margin-bottom: 4px;
}
.game-tags {
  display: flex;
  gap: 8px;
}
.info {
  margin-bottom: var(--gap-md);
}
.info-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: var(--font-size-main);
}
.desc {
  color: var(--text-color-sub);
  max-width: 60vw;
  text-align: right;
}
.actions {
  display: flex;
  justify-content: center;
  margin-bottom: var(--gap-md);
}
.start-btn {
  background: var(--primary-gradient);
  color: #fff;
  border: none;
  border-radius: 6px;
  padding: 10px 32px;
  font-size: var(--font-size-main);
  cursor: pointer;
  font-weight: 600;
  transition:
    background 0.2s,
    transform 0.15s;
  box-shadow: 0 2px 8px #1976d233;
}
.start-btn:hover {
  background: linear-gradient(90deg, #1565c0 0%, #67b1fb 100%);
  transform: scale(1.04);
}
.start-btn:active {
  background: linear-gradient(90deg, #1976d2 0%, #1565c0 100%);
  transform: scale(0.97);
}
.game-section {
  margin-top: var(--gap-lg);
  margin-bottom: var(--gap-lg);
  padding-bottom: var(--gap-sm);
  border-bottom: 1px solid var(--border-color);
}
.section-title {
  font-size: var(--font-size-title);
  font-weight: 600;
  margin-bottom: 12px;
  color: var(--text-color-main);
}
.section-content {
  font-size: var(--font-size-main);
  color: var(--text-color-sub);
  margin-bottom: 8px;
}
.screenshots {
  display: flex;
  gap: var(--gap-md);
  margin-bottom: 8px;
}
.screenshot-img {
  width: 120px;
  height: 80px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid #eee;
  background: #fafafa;
  transition:
    box-shadow 0.2s,
    transform 0.15s;
}
.screenshot-img:hover {
  box-shadow: 0 4px 16px #1976d233;
  transform: scale(1.05);
}
.screenshots-carousel {
  margin-bottom: 8px;
  border-radius: 12px;
  box-shadow: 0 2px 8px #1976d233;
  background: #fafafa;
}
.screenshots-carousel-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
}
.full-width-carousel {
  width: 100%;
  max-width: 100%;
}
.screenshots-carousel-wrapper {
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}
.rank-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 8px;
}
.rank-table th,
.rank-table td {
  border: 1px solid var(--border-color);
  padding: 6px 12px;
  text-align: center;
}
.rank-table th {
  background: var(--secondary-color);
  color: var(--text-color-light);
}
.keycap {
  display: inline-block;
  min-width: 1.8em;
  padding: 0 0.5em;
  margin: 0 2px;
  border: 1.5px solid #1976d2;
  border-radius: 6px;
  background: #f5f7fa;
  color: #1976d2;
  font-weight: 600;
  font-size: 1em;
  line-height: 1.7;
  text-align: center;
  box-shadow: 0 1px 2px #1976d211;
  user-select: none;
  vertical-align: middle;
  transition:
    border-color 0.2s,
    background 0.2s;
}
.keycap:hover {
  border-color: #1565c0;
  background: #e6f0fa;
}
.comment-group-title {
  font-size: 1.1em;
  font-weight: 700;
  color: #1976d2;
  margin: 16px 0 8px 0;
  letter-spacing: 1px;
}
.achievements-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 32px;
  margin: 16px 0 8px 0;
  padding: 0 32px;
}
.achievement-box {
  flex: 1 1 0;
  min-width: 0;
  max-width: 260px;
  box-sizing: border-box;
  background: #fff;
  border: 2.5px solid #1976d2;
  border-radius: 0 16px 0 16px;
  position: relative;
  padding: 18px 18px 14px 18px;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 12px #1976d211;
  transition:
    border-color 0.2s,
    box-shadow 0.2s;
  text-align: center;
  flex-basis: calc((100% - 2 * 32px - 2 * 32px) / 3);
}
/* 1. 优化评论区样式 */
.comment-item {
  background: var(--card-bg);
  border-radius: 6px;
  padding: 12px 16px;
  margin-bottom: 16px;
  color: var(--text-color-main);
  display: flex;
  align-items: center;
  gap: 16px;
  transition:
    box-shadow 0.2s,
    transform 0.15s;
  font-size: 1.08em;
  line-height: 1.7;
}
</style>
